#include "Widget.h"
#include <iostream>

template<class Interface>
inline void SafeRelease(Interface **ppInterfaceToRelease )
{
    if (*ppInterfaceToRelease != NULL)
    {
        (*ppInterfaceToRelease)->Release();

        (*ppInterfaceToRelease) = NULL;
    }
}

Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    setAttribute(Qt::WA_PaintOnScreen);
    resize(800,600);

}

Widget::~Widget()
{
    SafeRelease(&d2d1_factory_);
    SafeRelease(&render_target_);
    SafeRelease(&brush_);
}

void Widget::paintEvent(QPaintEvent *event)
{
    HRESULT hr = S_OK;
    if (FAILED(CreateDeviceResources())) {
        return ;
    }
    render_target_->BeginDraw();

    render_target_->Clear( D2D1::ColorF(D2D1::ColorF::SkyBlue) );

    D2D1_RECT_F rect = {0,0,200,300};
    render_target_->DrawRectangle(&rect,brush_);

    hr = render_target_->EndDraw();
    if (hr == D2DERR_RECREATE_TARGET) {
        DiscardDeviceResources();
    }

}

void Widget::resizeEvent(QResizeEvent *e)
{
    if (render_target_) {
        render_target_->Resize(D2D1::SizeU(e->size().width(),e->size().height()));
    }
}

QPaintEngine *Widget::paintEngine() const
{
    return nullptr;
}

HRESULT Widget::CreateDeviceResources()
{
    if (!render_target_) {
        HRESULT hr =  D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &d2d1_factory_);
        if (FAILED(hr)) {
            std::cerr << "D2D1CreateFactory" << std::endl;
            return hr;
        }

        D2D1_SIZE_U size = {800,600};
        hr = d2d1_factory_->CreateHwndRenderTarget(D2D1::RenderTargetProperties(),
                                                   D2D1::HwndRenderTargetProperties((HWND)this->winId(), size),
                                                   &render_target_);
        if (FAILED(hr)) {
            std::cerr << "CreateHwndRenderTarget" << std::endl;
            return hr;
        }
        D2D1_COLOR_F color = {1.0f,1.0f,0};
        hr = render_target_->CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF::Yellow),&brush_);
        if (FAILED(hr)) {
            return hr;
        }
    }
    return S_OK;
}

void Widget::DiscardDeviceResources()
{
    SafeRelease(&d2d1_factory_);
    SafeRelease(&render_target_);
    SafeRelease(&brush_);
}

